package com.fafu.control;

import com.fafu.model.Image;
import com.fafu.pojo.StudentInsertPojo;
import com.fafu.service.ImageService;
import com.fafu.service.ToolService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.spring.web.json.Json;
import util.Dictionary;
import util.JedisTool;
import util.JsonRsp;
import util.MyMap;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;

@Api("工具接口")
@RestController
@RequestMapping("/tool")
public class ToolControl {
    private Logger logger = LoggerFactory.getLogger(ToolControl.class);
    @Value("${mydata.pic.upload}")
    private String picUrl;

    @Value("${mydata.pic.type}")
    private List<String> picType;

    @Value("${mydata.pic.httpurl.prefix}")
    private String httpurl;

    @Value("${mydata.exc.upload}")
    private String excUrl;
    @Autowired
    private ImageService imageService;
    @Autowired
    private JedisTool jedisTool;
    @Autowired
    private ToolService toolService;
    private final static String EXCLE_NAME = "excelName";
    private final static String EXCEL_CLOCK = "excelClock";

    @ApiOperation("图片上传接口")
    @RequestMapping(value = "/picUpload", method = RequestMethod.POST)
    public JsonRsp picUplod(MultipartFile file) {
        try {
            logger.info("fileUpload");
            if(file == null) {
                logger.info("file is null");
                return JsonRsp.fail(Dictionary.CODE.FILE_UPLOAD_EMPTY, "文件为空");
            }
            if (file.isEmpty())
                return JsonRsp.fail(Dictionary.CODE.FILE_UPLOAD_EMPTY, "文件为空");
            String filename = file.getOriginalFilename();
            String postfix = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();//后缀
            if (!picType.contains(postfix))//判断是否为图片
                return JsonRsp.fail(Dictionary.CODE.FILE_UPLOAD_TYPE_ERROR, "非图片文件");
            String finalName = ToolControl.CreateName() + "." + postfix;
            File fileurl = new File(picUrl + "/" + finalName);
            //文件夹是否存在
            if (!fileurl.getParentFile().exists())
                fileurl.getParentFile().mkdirs();
            //文件保存到本地并且插入到数据库
            file.transferTo(fileurl);
            Image image = new Image();
            image.setUrl(httpurl + finalName);
            image.setUploadTime(System.currentTimeMillis());
            int picId = imageService.insert(image);
            Map<String, Object> remape = new HashMap<>();
            remape.put("picId", picId);
            remape.put("picUrl", httpurl + finalName);
            return JsonRsp.success(remape);
        } catch (Exception e) {
            logger.error("内部异常" + e);
            return JsonRsp.fail(Dictionary.CODE.SYSTEM_ERROR, "系统内部异常");
        }
    }

    @ApiOperation("excel上传接口")
    @RequestMapping(value = "/excUpload", method = RequestMethod.POST)
    public JsonRsp excUpload(MultipartFile file) {
        try {
            if (file.isEmpty())
                return JsonRsp.fail(Dictionary.CODE.FILE_UPLOAD_EMPTY, "文件为空");
            String filename = file.getOriginalFilename();
            String postfix = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();//后缀
            //检查文件类型
            if (!filename.matches("^.+\\.(?i)(xls)$") && !filename.matches("^.+\\.(?i)(xlsx)$"))
                return JsonRsp.fail(Dictionary.CODE.FILE_UPLOAD_TYPE_ERROR, "文件格式错误");

            String finalName = ToolControl.CreateName() + "." + postfix;
            File fileurl = new File(excUrl + "/" + finalName);

            if (!fileurl.getParentFile().exists()) //文件夹是否存在
                fileurl.getParentFile().mkdirs();
            file.transferTo(fileurl);//文件保存到本地

            //读取excel头。返回给前端。。让前端做映射
            boolean isExcel2003=true;
            if (filename.matches("^.+\\.(?i)(xlsx)$")) {
                isExcel2003 = false;
            }
            InputStream is = new FileInputStream(fileurl);
            Workbook wb = null;
            if(isExcel2003)
                wb = new HSSFWorkbook(is);
            else
                wb = new XSSFWorkbook(is);
            Sheet sheet = wb.getSheetAt(0);
            int rowCount  = sheet.getLastRowNum();
            Row row = sheet.getRow(0);//获得表头
            int cellCount = row.getLastCellNum();
            List<Map<String,Object>> reList = new ArrayList<>();
            for(int i = 0;i<cellCount;i++)
                reList.add(new MyMap().put("text",row.getCell(i).toString()).put("value",i).toMap());
            //数据加入到redis
            jedisTool.set4Value(EXCLE_NAME,finalName,30*60L);//存30min
            return JsonRsp.success(new MyMap().put("title",reList).put("fileName",finalName).toMap());
        } catch (Exception e) {
            logger.error("内部异常" + e);
            return JsonRsp.fail(Dictionary.CODE.SYSTEM_ERROR, "系统内部异常");
        }
    }
    @ApiOperation("数据插入")
    @RequestMapping(value = "/infoInsert", method = RequestMethod.POST)
    public JsonRsp infoInsert(
            @RequestBody @ApiParam("映射")StudentInsertPojo shine
            ,@RequestParam("fileName") @ApiParam("文件名") String fileName) {
            try{
                synchronized (ToolControl.class){
                    String jFilName = jedisTool.getValue(EXCLE_NAME);
                    if(jFilName == null)
                        return JsonRsp.fail(Dictionary.CODE.OPERATION_TIME_OUT,"操作超时");
                    else if(!jFilName.equals(fileName))
                        return JsonRsp.fail(Dictionary.CODE.OTHER_MANAGER_OPERATION,"其他管理员正在操作");
                    else if(jedisTool.getValue(EXCEL_CLOCK) != null)
                        return JsonRsp.fail(Dictionary.CODE.OTHER_MANAGER_OPERATION,"其他管理员正在操作");
                    jedisTool.set4Value(EXCEL_CLOCK,"excelClock",30*60L); //加锁
                }
                String fileUrl = excUrl+"/"+fileName;
                //开始插入学生数据
                Map<String,Object> reMap = toolService.studentInsert(new MyMap().put("shine",shine).put("fileUrl",fileUrl).toMap());
                //结束插入学生数据
                jedisTool.deletKey(EXCEL_CLOCK);//释放锁
                return JsonRsp.success(reMap);
            }catch (Exception e){
                logger.error(""+e);
                jedisTool.deletKey(EXCEL_CLOCK);//释放锁
                return JsonRsp.fail(Dictionary.CODE.SYSTEM_ERROR,"系统内部错误");
            }
    }
    public static String CreateName() {
        StringBuilder name = new StringBuilder();
        name.append(System.currentTimeMillis());
        String uuid = UUID.randomUUID().toString().substring(0, 5);
        name.append(uuid);
        return name.toString();
    }
}
